interface setItemsType<T>{
    [propsName:string]:T
}

export default class Set<T>{
    private items:setItemsType<T>;

    constructor(){
        this.items={}
    }
    // ADT
    has(element:any):boolean{
        return Object.prototype.hasOwnProperty.call(this.items,element)
    }
    add(element:any){
        if(!this.has(element)){
            this.items[element]=element
        }
    }
    delete(element:any){
        if(this.has(element)){
            delete this.items[element];
            return true
        }
        return false
    }
    clear(){
        this.items={}
    }
    size(){
        let count=0
        for(let key in this.items){
            if(this.items.hasOwnProperty(key)){
                count++
            }
        }
        return count 
    }
    values(){
        let values=[];
        for(let key in this.items){
            if(this.items.hasOwnProperty(key)){
                values.push(key);
            }
        }
        return values
    }
    union(otherSet:Set<T>){
        const unionSet=new Set();
        // const values=this.values();
        this.values().forEach(value => {
            unionSet.add(value)
        });
        otherSet.values().forEach(value=>unionSet.add(value))
        return unionSet
    }

    // 交集
    intersection(otherset:Set<T>){
        const intersectionSet = new Set();
        const values=this.values()
        const otherValues=otherset.values();
        let smallerSet=otherValues
        let biggerSet=values
        if(otherValues.length-values.length>0){
            biggerSet=otherValues
            smallerSet=values
        }
        smallerSet.forEach(value=>{
            if(biggerSet.includes(value)){
                intersectionSet.add(value)
            }
        })
        return intersectionSet
    }
    // 差集
    difference(otherSet:Set<T>){
        const differenceSet=new Set();
        this.values().forEach(value=>{
            if(!otherSet.has(value)){
                differenceSet.add(value)
            }
        })
    }
    isSubsetOf(otherSet:Set<T>){
        if(this.size()>otherSet.size()){
            return false
        }
        return this.values().every(value=>{
            return otherSet.has(value)
        })
    }
}